/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
package fr.jade.service.fm.reactor;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;

import fr.jade.base.JadeBaseComponent;
import fr.jade.service.fm.deployment.DeploymentTask;
import fr.jade.service.fm.deployment.NewComponentTask;
import fr.jade.util.JadeException;

public class BasicPolicyScheduler extends JadeBaseComponent implements Policy {
  // binding
  protected static final String clientPoliciesItfNamePrefix = "clientpolicies";
  protected Map<String, Policy> clientPolicies = new HashMap<String, Policy>();

  public int getPriorityLevel(){
    return 0;
  }
  
  public Set<DeploymentTask> execute(Map<Component, NewComponentTask> context, Set<Component> failedCmps_M, Set<Component> impactedCmps_M, Component newNode_M) throws JadeException {
    log("Schedule policies");
    Policy[] policies = new Policy[clientPolicies.size()];
    for(Policy p : clientPolicies.values()){
      policies[p.getPriorityLevel()]=p;
    }
    Set<DeploymentTask> tasks = new HashSet<DeploymentTask>();
    for(Policy p : policies){
      tasks.addAll(p.execute(context, failedCmps_M, impactedCmps_M, newNode_M));
    }
    return tasks;
  }

  // implem of binding controller
  public String[] listFc() {
    return super.concat(clientPolicies.keySet(), super.listFc());
  }

  public Object lookupFc(final String itfName) throws NoSuchInterfaceException {
    if (itfName.startsWith(clientPoliciesItfNamePrefix)) {
      //if(!clientPolicies.containsKey(itfName)) throw new NoSuchInterfaceException(itfName);
      return clientPolicies.get(itfName);
    } 
    return super.lookupFc(itfName);
  }

  public void bindFc(final String itfName, final Object itfValue) throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
    if (itfName.startsWith(clientPoliciesItfNamePrefix)) {
      clientPolicies.put(itfName, (Policy)itfValue);
    } else super.bindFc(itfName, itfValue);
  }

  public void unbindFc(final String itfName) throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
    if (itfName.startsWith(clientPoliciesItfNamePrefix)) {
      if(!clientPolicies.containsKey(itfName)) throw new NoSuchInterfaceException(itfName);
        clientPolicies.remove(itfName);
    } else super.unbindFc(itfName);
  }
  
}
